package service

import (
	sqlc "bgs/db/sqlc"
	"bgs/util"
	"context"
)

// 计算商品分销佣金X 分销佣金X=商品价格*佣金比例
func calcProductDistributorCommission(price int32, percentOff int32) int64 {
	return int64(util.Fix0(float64(price) * float64(percentOff) / 1000))
}

// 计算商品订单奖励金X 订单奖励金X=商品价格*奖励金比例
func calcProductBonus(price int32, bonusRate int32) int64 {
	return int64(util.Fix0(float64(price) * float64(bonusRate) / 1000))
}

// CalculateOrderParam 计算订单参数
type CalculateOrderParam struct {
	OrderDetailPtrs []*sqlc.OrderDetail
	OrderPtr        *sqlc.Order
}



// CalculatePlatformCommission 计算订单的平台佣金 (主动) 平台佣金X=商品售卖金额*佣金比例
func (s *OrderServiceImp) CalculatePlatformCommission(ctx context.Context, q *sqlc.Queries, ptr *CalculateOrderParam) (platformCommission uint64, err error) {
	// slog := util.NewContextLogger(ctx, s.slog)
	// todo: percentOff 目前返回0
	var productAmount, percentOff uint64
	for _, itemPtr := range ptr.OrderDetailPtrs {
		productAmount += uint64(itemPtr.Price * itemPtr.Quantity)
	}
	platformCommission = percentOff * productAmount
	return
}

// 求和（商品分销佣金X*数量Y）【商品特指为完成订单时未退款，且有分销佣金的商品】;分销佣金X=商品售卖价格*佣金比例
// CalculateDistributorCommission 计算分销订单佣金 (主动)
func (s *OrderServiceImp) CalculateDistributorCommission(ctx context.Context, q *sqlc.Queries, ptr *CalculateOrderParam) (distributorCommission uint64, err error) {
	// slog := util.NewContextLogger(ctx, s.slog)

	// 获取品牌的供货商品设置
	distributeProducts, err := q.ListBrandDistributeProductsByBrandID(ctx, ptr.OrderPtr.BrandID)
	if err != nil {
		return
	}
	mapOfDistributeProduct := util.SliceToMapInt64(util.ToGenericSlice(distributeProducts), func(m map[int64]interface{}, v interface{}) {
		val := v.(sqlc.BrandDistributeProduct)
		m[val.ProductID] = v
	})

	for _, itemPtr := range ptr.OrderDetailPtrs {
		if v, found := mapOfDistributeProduct[itemPtr.ProductID]; found {
			val := v.(sqlc.BrandDistributeProduct)
			// 单个商品产生的佣金
			// 这边暂时用原价price,没有用到percent_sale
			itemOff := calcProductDistributorCommission(itemPtr.Price, val.PercentOff)
			if itemOff > 0 {
				offAmountOfItem := itemOff * int64(itemPtr.Quantity) // 明细佣金
				_, err = q.UpsertOrderDistributorCommission(ctx, sqlc.UpsertOrderDistributorCommissionParams{
					OrderID:           itemPtr.OrderID,
					OrderSerialNumber: itemPtr.OrderSerialNumber,
					ProductID:         itemPtr.ProductID,
					ProductSpecID:     itemPtr.ProductSpecID,
					ProductSpecKey:    itemPtr.ProductSpecKey,
					Amount:            itemPtr.Amount, //这里不用考虑退的钱
					PercentOff:        val.PercentOff,
					OffAmount:         offAmountOfItem,
				})
				if err != nil {
					return
				}
				distributorCommission += uint64(offAmountOfItem)
			}
		}
	}
	return
}

// 求和（商品奖励金X*数量Y）【商品特指为完成订单时未退款，且有代言奖励金的商品】;奖励金X=商品售卖价格*佣金比例
// CalculateBonus 计算订单奖励金 (主动)
func (s *OrderServiceImp) CalculateBonus(ctx context.Context, q *sqlc.Queries, ptr *CalculateOrderParam) (bonusAmount uint64, err error) {
	// slog := util.NewContextLogger(ctx, s.slog)

	// 订单是代言人活动产生,需要通过parentActivityID获取品牌发布的活动佣金奖励设置
	var bonusSettings []sqlc.ActivityConsignmentBonusSetting
	bonusSettings, err = q.ListNormalActivityConsignmentBonusSettingsByActivityID(ctx, ptr.OrderPtr.ParentActivityID.Int64)
	if err != nil {
		return
	}
	mapOfBonusSetting := util.SliceToMapInt64(util.ToGenericSlice(bonusSettings), func(m map[int64]interface{}, v interface{}) {
		val := v.(sqlc.ActivityConsignmentBonusSetting)
		m[val.ProductID] = v
	})

	for _, itemPtr := range ptr.OrderDetailPtrs {
		if v, found := mapOfBonusSetting[itemPtr.ProductID]; found {
			val := v.(sqlc.ActivityConsignmentBonusSetting)
			// 单个商品产生的佣金
			itemBonus := calcProductBonus(itemPtr.Price, val.BonusRate)
			if itemBonus > 0 {
				bonusAmountOfItem := itemBonus * int64(itemPtr.Quantity) // 明细佣金
				_, err = q.UpsertOrderBonus(ctx, sqlc.UpsertOrderBonusParams{
					OrderID:           itemPtr.OrderID,
					OrderSerialNumber: itemPtr.OrderSerialNumber,
					ProductID:         itemPtr.ProductID,
					ProductSpecID:     itemPtr.ProductSpecID,
					ProductSpecKey:    itemPtr.ProductSpecKey,
					Amount:            itemPtr.Amount, //这里不用考虑退的钱
					BonusRate:         val.BonusRate,
					BonusAmount:       bonusAmountOfItem,
				})
				if err != nil {
					return
				}
				bonusAmount += uint64(bonusAmountOfItem)
			}
		}
	}
	return
}

// CalculateRefundParam 计算退款产生的回退佣金参数
type CalculateRefundParam struct {
	// OrderPtr            *sqlc.Order
	AfterSalePtr        *sqlc.AfterSale
	AfterSaleDetailPtrs []*sqlc.AfterSaleDetail
}

// 求和（退款商品分销订单佣金X*数量Y），【商品特指为售后单申请退款的商品】;分销佣金X=商品价格*佣金比例
// CalculateRefundPlatformCommission 计算退款产生的回退平台佣金 (主动)
func (s *OrderServiceImp) CalculateRefundPlatformCommission(ctx context.Context, q *sqlc.Queries, ptr *CalculateRefundParam) (platformCommission uint64, err error) {
	// slog := util.NewContextLogger(ctx, s.slog)
	var productAmount, percentOff uint64
	for _, itemPtr := range ptr.AfterSaleDetailPtrs {
		productAmount += uint64(itemPtr.Price * itemPtr.Quantity)
	}
	platformCommission = percentOff * productAmount
	return
}

// 求和（退款商品分销订单佣金X*数量Y），【商品特指为售后单申请退款的商品】;分销佣金X=商品价格*佣金比例
// CalculateRefundBonus 计算退款产生的回退分销佣金 (主动)
func (s *OrderServiceImp) CalculateRefundDistributorCommission(ctx context.Context, q *sqlc.Queries, ptr *CalculateRefundParam) (distributorCommission uint64, err error) {
	// slog := util.NewContextLogger(ctx, s.slog)
	orderID := ptr.AfterSalePtr.OrderID
	orderDistributorCommissionPtrs, err := s.ListOrderDistributorCommissionPtrsByOrderID(ctx, q, orderID)
	if err != nil {
		return
	}
	mapOfDistributorCommissions := util.SliceToMapInt64(util.ToGenericSlice(orderDistributorCommissionPtrs), func(m map[int64]interface{}, v interface{}) {
		val := v.(*sqlc.OrderDistributorCommission)
		m[val.ProductID] = v
	})

	for _, itemPtr := range ptr.AfterSaleDetailPtrs {
		if v, found := mapOfDistributorCommissions[itemPtr.ProductID]; found {
			val := v.(*sqlc.OrderDistributorCommission)
			// 单个商品产生的佣金
			itemOff := calcProductDistributorCommission(itemPtr.Price, val.PercentOff)
			if itemOff > 0 {
				offAmountOfItem := itemOff * int64(itemPtr.Quantity) // 售后明细佣金
				distributorCommission += uint64(offAmountOfItem)
			}
		}
	}
	return
}

// 求和（退款商品订单奖励金X*数量Y），【商品特指为售后单申请退款的商品】;奖励金X=商品价格*奖励金比例
// CalculateRefundBonus 计算退款产生的回退奖励金 (主动)
func (s *OrderServiceImp) CalculateRefundBonus(ctx context.Context, q *sqlc.Queries, ptr *CalculateRefundParam) (bonusAmount uint64, err error) {
	// slog := util.NewContextLogger(ctx, s.slog)

	// afterSaleDetails, err := q.ListNormalAfterSaleDetailsByAfterSaleID(ctx, p.AfterSalePtr.ID)
	// if err != nil {
	// 	return
	// }
	// slog.Infof("1、获取订单明细 ok")

	// 订单是代言人活动产生,需要通过parentActivityID获取品牌发布的活动佣金奖励设置
	// var bonusSettings []sqlc.ActivityConsignmentBonusSetting
	// bonusSettings, err = q.ListNormalActivityConsignmentBonusSettingsByActivityID(ctx, ptr.OrderPtr.ParentActivityID.Int64)
	// if err != nil {
	// 	return
	// }
	// mapOfBonusSetting := util.SliceToMapInt64(util.ToGenericSlice(bonusSettings), func(m map[int64]interface{}, v interface{}) {
	// 	val := v.(sqlc.ActivityConsignmentBonusSetting)
	// 	m[val.ProductID] = v
	// })

	orderID := ptr.AfterSalePtr.OrderID
	orderBonusPtrs, err := s.ListOrderBonusPtrsByOrderID(ctx, q, orderID)
	if err != nil {
		return
	}
	mapOfBonuses := util.SliceToMapInt64(util.ToGenericSlice(orderBonusPtrs), func(m map[int64]interface{}, v interface{}) {
		val := v.(*sqlc.OrderBonuse)
		m[val.ProductID] = v
	})

	for _, itemPtr := range ptr.AfterSaleDetailPtrs {
		if v, found := mapOfBonuses[itemPtr.ProductID]; found {
			val := v.(*sqlc.OrderBonuse)
			// 单个商品产生的佣金
			itemBonus := calcProductBonus(itemPtr.Price, val.BonusRate)
			if itemBonus > 0 {
				bonusAmountOfItem := itemBonus * int64(itemPtr.Quantity) // 售后明细佣金
				bonusAmount += uint64(bonusAmountOfItem)
			}
		}
	}
	return
}

// [OBSOLETE]
// ((本次售后退款金额*(已发订单奖励金-已发已退订单奖励金))/(已结订单金额-已结已退订单金额))
// CalculateRefundBonus 计算退款产生的回退佣金 (主动)
// func (s *OrderServiceImp) CalculateRefundBonusOld(ctx context.Context, p CalculateRefundParam) (refundBonusAmount uint64, err error) {
// 	slog := util.NewContextLogger(ctx, s.slog)

// 	afterSaleAmountOfCurrent := util.AbsFromInt64ToUint64(p.AfterSalePtr.Amount)        // 本次售后退款金额
// 	orderBonusAmount := util.AbsFromInt64ToUint64(p.OrderPtr.BonusAmount)               // 已发订单奖励金
// 	refundedOrderBonusAmount := util.AbsFromInt64ToUint64(p.OrderPtr.RefundBonusAmount) // 已发已退订单奖励金
// 	orderAmount := util.AbsFromInt64ToUint64(p.OrderPtr.ActualAmount)                   // 已结订单金额
// 	refundedOrderAmount := util.AbsFromInt64ToUint64(p.OrderPtr.RefundAmount)           // 已结已退订单金额

// 	refundBonusAmount = s.calcByFormulaOfMultipleRefund(afterSaleAmountOfCurrent, orderBonusAmount, refundedOrderBonusAmount, orderAmount, refundedOrderAmount)

// 	slog.Infof("本次售后单(%s)应退的订单奖励金%d", p.AfterSalePtr.SerialNumber, refundBonusAmount)
// 	return
// }

// [OBSOLETE]
// 参数: refund 本次结算金额
//      feeOfAll 已收手续费
//      feeOfReturn 已收已退手续费
//      total 已结金额
//      refunded 已结已退金额
// calcByFormulaOfMultipleRefund 多次退的计算公式
// func (s *OrderServiceImp) calcByFormulaOfMultipleRefund(refund uint64, feeOfAll uint64, feeOfReturn uint64, total uint64, refunded uint64) uint64 {
// 	return (refund * (feeOfAll - feeOfReturn)) / (total - refunded)
// }

// GetFinalBonus 获取订单最后的推广金 返回是正
func (s *OrderServiceImp) GetFinalBonus(ctx context.Context, q *sqlc.Queries, orderPtr *sqlc.Order) int64 {
	return 0 - (orderPtr.BonusAmount + orderPtr.RefundBonusAmount)
}
